package com.cinema.api.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cinema.api.constant.OrderStatus;
import com.cinema.api.mapper.ArrangementMapper;
import com.cinema.api.mapper.FilmMapper;
import com.cinema.api.mapper.UserMapper;
import com.cinema.api.model.dto.OrderDTO;
import com.cinema.api.model.entity.*;
import com.cinema.api.mapper.OrderMapper;
import com.cinema.api.model.enums.ResultCodeEnum;
import com.cinema.api.model.exception.BizException;
import com.cinema.api.service.ArrangementService;
import com.cinema.api.service.OrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cinema.api.utils.BaseUtil;
import com.cinema.api.utils.DataTimeUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.joda.time.Minutes;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xhh
 * @since 2021-12-31
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private ArrangementMapper arrangementMapper;

    @Resource
    private ArrangementService arrangementService;

    @Resource
    private UserMapper userMapper;

    @Resource
    private FilmMapper filmMapper;
    /**
     * 统计电影排片票房
     */
    @Override
    public String getPrices(String fid) {
        QueryWrapper<Arrangement> wrapper = new QueryWrapper<>();
        wrapper.in("fid", fid)
                .eq("is_delete", 0);
        List<Arrangement> arrangements = arrangementMapper.selectList(wrapper);
        DecimalFormat df = new DecimalFormat("#0.00");
        Double prices = 0.00;
        for (Arrangement arrangement : arrangements) {
            // 获取该电影对应的场次ID
            if (BaseUtil.isEmpty(orderMapper.getPrices(arrangement.getId()))) {
                continue;
            }
            Double price = Double.parseDouble(String.valueOf(orderMapper.getPrices(arrangement.getId())));
            prices += price;
        }
        String result = String.valueOf(prices);
        if (result == null || "null".equals(result)) {
            result = "0.00";
        }
        return result;
    }

    /**
     *  返回所有订单信息以及其相关信息
     */
    @Override
    public List<OrderDTO> findAll() throws ParseException {
        QueryWrapper<Order> wrapper = new QueryWrapper<>();
        wrapper.eq("is_delete", 0);
        return findOrderByWrapper(wrapper);
    }

    /**
     * 分页 返回所有订单信息
     */
    @Override
    public PageInfo<OrderDTO> findAllByPage(int page, int limit) throws ParseException {
        // 使用Mybatis分页插件
        // PageHelper.startPage(page, limit);
        QueryWrapper<Order> wrapper = new QueryWrapper<>();
        wrapper.eq("is_delete", 0);
        List<OrderDTO> orderByWrapper = findOrderByWrapper(wrapper);
        return new PageInfo<>(orderByWrapper);
    }

    /**
     *  更新订单状态
     */
    @Override
    public void update(Order order) {
        orderMapper.updateById(order);
    }

    /**
     *  创建订单
     */
    @Override
    public void create(Cart cart) {
        List<Integer> seatsHaveSelect = arrangementService.getSeatsHaveSelect(cart.getAid());
        String[] split = cart.getSeats().split("号");
        for (String s : split) {
            // 判断订单的座位是否已被其他用户预订
            if (seatsHaveSelect.contains(Integer.parseInt(s))) {
                throw new BizException(2003, "该订单已在购物车中待太久了，座位已被其他用户预订，请先删除该订单，再重新选座！");
            }
        }
        // 正常则新建订单
        Order order = new Order();
        order.setId(UUID.randomUUID().toString());
        order.setUid(cart.getUid());
        order.setAid(cart.getAid());
        order.setPhone(cart.getPhone());
        order.setSeats(cart.getSeats());
        order.setStatus(cart.getStatus());
        order.setIsDelete(0);
        order.setCreateTime(DataTimeUtil.getNowTimeString());
        order.setPrice(cart.getPrice());
        if (cart.getStatus() == 2) {
            // 已支付状态
            order.setPayTime(DataTimeUtil.getNowTimeString());
        }
        orderMapper.insert(order);

        // 添加电影热度（根据新增订购座位的个数）
        Film film = filmMapper.selectById(arrangementService.findById(cart.getAid()).getFid());
        film.setHot(film.getHot() + split.length);
        filmMapper.updateById(film);
    }

    /**
     * 根据用户Id查询用户订单
     */
    @Override
    public List<OrderDTO> findByUid(String uid) throws ParseException {
        QueryWrapper<Order> wrapper = new QueryWrapper<>();
        wrapper.in("uid", uid)
                .eq("is_delete", 0)
                .orderByDesc("create_time");
        return findOrderByWrapper(wrapper);
    }

    /**
     * 根据Id删除用户订单
     */
    @Override
    public void deleteById(String id) {
        orderMapper.deleteById(id);
    }

    /**
     * 根据订单Id 支付订单 更改状态
     */
    @Override
    public void payById(String id) {
        Order order = orderMapper.selectById(id);
        // 判断订单是否存在（避免空指针异常）
        if (BaseUtil.isEmpty(order)) {
            throw new BizException(2003, "订单信息不存在！");
        }
        // 判断订单是否支付超时（15分钟）避免用户不刷新页面 直接点击支付
        if (DataTimeUtil.parseTimeStamp(order.getCreateTime()) + OrderStatus.EXPIRATION_TIME < System.currentTimeMillis()) {
            order.setStatus(OrderStatus.PAYMENT_FAILED);
            order.setSeats("");
            orderMapper.updateById(order);
            throw new BizException(2003, "订单支付已超时，请重新购票！");
        }
        order.setStatus(OrderStatus.PAYMENT_SUCCESSFUL);
        order.setPayTime(DataTimeUtil.getNowTimeString());
        orderMapper.updateById(order);
    }


    /**
     *  根据订单信息Order返回订单相关信息
     */
    private List<OrderDTO> findOrderByWrapper(QueryWrapper<Order> wrapper) throws ParseException {
        // 所有订单信息
        List<Order> orders = orderMapper.selectList(wrapper);
        // 结果信息
        List<OrderDTO> result = new ArrayList<>();
        // 获取信息并赋值返回
        for (Order order : orders) {
            OrderDTO orderDTO = new OrderDTO();
            // 设置订单信息
            // 判断订单是否支付超时（15分钟）
            if (DataTimeUtil.parseTimeStamp(order.getCreateTime()) + OrderStatus.EXPIRATION_TIME < System.currentTimeMillis() && order.getStatus() == 0) {
                order.setStatus(OrderStatus.PAYMENT_FAILED);
                order.setSeats("");
                orderMapper.updateById(order);
            }
            // 订单状态为待支付时，返回剩余时间
            if (order.getStatus() == 0) {
                SimpleDateFormat format =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Minutes minutes = Minutes.minutesBetween(new DateTime(format.parse(order.getCreateTime())), new DateTime(format.parse(DataTimeUtil.getNowTimeString())));
                orderDTO.setExpireTime(String.valueOf(15-minutes.getMinutes()));
            }
            orderDTO.setOrder(order);
            // 设置用户信息
            orderDTO.setUser(userMapper.selectById(order.getUid()));
            // 设置排片信息
            Arrangement arrangement = arrangementMapper.selectById(order.getAid());
            if (BaseUtil.isNotEmpty(arrangement)) {
                orderDTO.setArrangement(arrangement);
                // 设置电影信息
                orderDTO.setFilm(filmMapper.selectById(arrangement.getFid()));
            }
            result.add(orderDTO);
        }
        return result;
    }

}
